🛒 Step 6: Checkout Module – Low Level Design (LLD)
This document describes the low-level design and implementation details for the checkout feature module, handling address selection, payment processing, and order confirmation in the Angular e-commerce app.
📦 Module Structure
src/
├── app/
│ └── features/
│ └── checkout/
│ ├── components/
│ │ ├── address-selection/
│ │ ├── payment/
│ │ └── order-confirmation/
│ ├── services/
│ │ └── checkout.service.ts
│ ├── store/
│ │ ├── checkout.actions.ts
│ │ ├── checkout.reducer.ts
│ │ ├── checkout.effects.ts
│ │ └── checkout.selectors.ts
│ ├── models/
│ │ └── checkout.model.ts
│ ├── checkout-routing.module.ts
│ └── checkout.module.ts
🧱 Component Breakdown
🏠 AddressSelectionComponent
- Displays saved addresses for user to select for delivery
- Option to add/edit addresses (opens modal or navigates to AddressFormComponent)
- Validates selected address before proceeding
💳 PaymentComponent
- Supports multiple payment methods (credit card, PayPal, wallet)
- Uses reactive forms with validation for card details
- Handles payment authorization and error states
✅ OrderConfirmationComponent
- Shows order summary, delivery address, payment method
- Confirms order placement and displays success or failure messages
- Option to view order details or continue shopping
🧪 Service: CheckoutService
Manages checkout-related API calls.
@Injectable({ providedIn: "root" })
export class CheckoutService {
constructor(private http: HttpClient) {}
getUserAddresses(): Observable<Address[]> {
return this.http.get<Address[]>("/api/user/addresses");
}
processPayment(paymentInfo: PaymentInfo): Observable<PaymentResponse> {
return this.http.post<PaymentResponse>(
"/api/checkout/payment",
paymentInfo
);
}
placeOrder(order: OrderRequest): Observable<OrderResponse> {
return this.http.post<OrderResponse>("/api/checkout/order", order);
}
}
🧩 NgRx Store (optional)
✅ Actions – checkout.actions.ts
export const loadAddresses = createAction("[Checkout] Load Addresses");
export const loadAddressesSuccess = createAction(
"[Checkout] Load Addresses Success",
props<{ addresses: Address[] }>()
);
export const submitPayment = createAction(
"[Checkout] Submit Payment",
props<{ paymentInfo: PaymentInfo }>()
);
export const submitPaymentSuccess = createAction(
"[Checkout] Submit Payment Success"
);
export const submitPaymentFailure = createAction(
"[Checkout] Submit Payment Failure",
props<{ error: any }>()
);
export const placeOrder = createAction(
"[Checkout] Place Order",
props<{ orderRequest: OrderRequest }>()
);
export const placeOrderSuccess = createAction(
"[Checkout] Place Order Success",
props<{ orderResponse: OrderResponse }>()
);
export const placeOrderFailure = createAction(
"[Checkout] Place Order Failure",
props<{ error: any }>()
);
🔁 Reducer – checkout.reducer.ts
Manages state slices for addresses, payment status, order confirmation, loading flags, and error messages.
🌐 Effects – checkout.effects.ts
Handles side effects such as fetching addresses, processing payments, and placing orders asynchronously.
🔍 Selectors – checkout.selectors.ts
export const selectAddresses = createSelector(
selectCheckoutState,
(state) => state.addresses
);
export const selectPaymentStatus = createSelector(
selectCheckoutState,
(state) => state.paymentStatus
);
export const selectOrderConfirmation = createSelector(
selectCheckoutState,
(state) => state.orderConfirmation
);
🔄 API Contracts
| Endpoint | Method | Request Body | Response |
|---|---|---|---|
/user/addresses |
GET | – | Address[] |
/checkout/payment |
POST | PaymentInfo |
PaymentResponse |
/checkout/order |
POST | OrderRequest |
OrderResponse |
📐 Models
export interface PaymentInfo {
method: string;
cardNumber?: string;
expiryDate?: string;
cvv?: string;
paypalId?: string;
walletId?: string;
}
export interface PaymentResponse {
success: boolean;
transactionId?: string;
errorMessage?: string;
}
export interface OrderRequest {
cartId: string;
addressId: string;
paymentTransactionId: string;
}
export interface OrderResponse {
orderId: string;
status: string;
estimatedDelivery: string;
}
🚦 Routing & Guards
const routes: Routes = [
{
path: "address-selection",
component: AddressSelectionComponent,
canActivate: [AuthGuard],
},
{ path: "payment", component: PaymentComponent, canActivate: [AuthGuard] },
{
path: "order-confirmation",
component: OrderConfirmationComponent,
canActivate: [AuthGuard],
},
];
🔐 Security & UX
- Use
AuthGuardfor all checkout routes - Validate forms thoroughly (address, payment)
- Show loaders during API calls and error/success feedback
- Prevent multiple submissions of payment/order requests
✅ Responsibilities Summary
| Part | Responsibility |
|---|---|
| AddressSelectionComponent | Select or add delivery address |
| PaymentComponent | Process payment through supported methods |
| OrderConfirmationComponent | Confirm and display order details |
| CheckoutService | API communication for checkout flow |